package me.youline.dataServer.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.transaction.Transactional;

import me.youline.dataServer.entity.PublicMessage.MsgStatus;
import me.youline.dataServer.entity.PublicMessageIndex;
import me.youline.dataServer.utils.IdPageSqlHelper;
import me.youline.dataServer.utils.IdPagination;
import org.perf4j.aop.Profiled;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Component;

@Component
public class PubMsgIndexDAO {

	private static final String TABLE_NAME = "yline_social_msg_index";

	private static String insert_SQL = "insert into " + TABLE_NAME
			+ " (msgId,creatorId,status,displayPicUrl) values(?,?,?,?)";

	private static String UPDATE_STATUS_SQL = "update " + TABLE_NAME
			+ " set status = ? where msgId = ?";

	private static String DELETE_SQL = " delete from " + TABLE_NAME
			+ " where msgId in (:msgIds)";

	private static String QUERY_USER_PERSONAL_MSG_SQL = "select * from "
			+ TABLE_NAME
			+ " where %s and creatorId = ? and status = ? order by msgId desc %s ";
	
	private static String QUERY_MSG_INDEX_SQL = "select * from "
			+ TABLE_NAME
			+ " where %s order by msgId desc %s ";

	private static String QUERY_USERS_PUBLIC_MSG_SQL = "select * from "
			+ TABLE_NAME
			+ " where %s and creatorId in (:userIds) and status = :status order by msgId desc %s ";
	
	private static String QUERY_MSG_INDEX = "select * from " + TABLE_NAME
			+ " where msgId = ?  ";
	
	@Autowired
	private JdbcTemplate jdbcTemplate;

	@Autowired
	private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

	private RowMapper<PublicMessageIndex> ROW_MAPPER = new RowMapper<PublicMessageIndex>() {

		@Override
		public PublicMessageIndex mapRow(ResultSet rs, int rowNum)
				throws SQLException {
			PublicMessageIndex index = new PublicMessageIndex(
					rs.getLong("msgId"), rs.getLong("creatorId"),
					rs.getString("displayPicUrl"),
					MsgStatus.values()[rs.getInt("status")],
					rs.getTimestamp("createTime")
					);
			return index;
		}
	};

	/**
	 * 根据消息id获取消息索引
	 * 
	 * @param msgId
	 * @return
	 */
	@Profiled(tag = "dao-根据消息ID获取消息索引")
	public PublicMessageIndex getIndexBymsgId(Long msgId) {
		try {
			return jdbcTemplate.queryForObject(QUERY_MSG_INDEX,
					new Object[] { msgId }, ROW_MAPPER);
		} catch (EmptyResultDataAccessException e) {
			return null;
		}
	}


	/**
	 * 添加公开消息索引
	 * @param index
	 */
	@Transactional
	@Profiled(tag = "dao-添加消息索引")
	public void addPublicMsgIndex(PublicMessageIndex index) {
		jdbcTemplate.update(insert_SQL,
				new Object[] { index.getMsgId(), index.getCreatorId(),
						index.getMsgStatus().ordinal(), index.getDisplayPicUrl() });
	}

	/**
	 * 更新消息状态标志位
	 * 
	 * @param msgId
	 * @param status
	 */
	@Transactional
	@Profiled(tag = "dao-更新消息状态")
	public void updateMsgStatus(Long msgId, MsgStatus status) {
		jdbcTemplate.update(UPDATE_STATUS_SQL, new Object[] { status.ordinal(),
				msgId });
	}

	/**
	 * 分页获取当前用户发送的不同状态的公告消息，如果是选择个人可见消息状态，则公开和个人消息都可以被读取出来。
	 * 
	 * @param userId
	 * @param status
	 * @param page
	 * @return
	 */
	@Transactional
	@Profiled(tag = "dao-获取指定用户的指定状态下的消息ID")
	public List<PublicMessageIndex> getMsgIdsByUserId(Long userId, MsgStatus status,
			IdPagination page) {
		IdPageSqlHelper helper = IdPageSqlHelper.create(page, "msgId");
		String sql = String.format(QUERY_USER_PERSONAL_MSG_SQL,
				helper.getPagingSqlCondition(), helper.getSizeSqlCondition());
		Object[] data = null;
		if (helper.getIds().length == 0) {
			data = new Object[] { userId, status.ordinal() };
		} else if (helper.getIds().length == 1) {
			data = new Object[] { helper.getIds()[0], userId, status.ordinal() };
		} else if (helper.getIds().length == 2) {
			data = new Object[] { helper.getIds()[0], helper.getIds()[1],
					userId, status.ordinal() };
		}
		return jdbcTemplate.query(sql, data, ROW_MAPPER);
	}

	/**
	 * 分页获取用户列表发送的公开公告消息
	 * 
	 * @param userId
	 * @param page
	 * @return
	 */
	@Profiled(tag = "dao-获取指定用户发送的公开消息")
	public List<PublicMessageIndex> getPublicMsgIdsByUserIds(List<Long> userIds,
			IdPagination page) {
		IdPageSqlHelper helper = IdPageSqlHelper.create(page, "msgId");
		String sql = String.format(QUERY_USERS_PUBLIC_MSG_SQL,
				helper.getSqlParamCondition(), helper.getSizeSqlCondition());
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("userIds", userIds);
		map.putAll(helper.getIdsMap());
		map.put("status", MsgStatus.publicMsg.ordinal());
		return namedParameterJdbcTemplate.query(sql, map, ROW_MAPPER);
	}

	/**
	 * 根据消息ID，删除消息索引
	 * 
	 * @param msgIds
	 */
	@Transactional
	@Profiled(tag = "dao-根据消息ID，删除消息索引")
	public void deleteMsgIndex(List<Long> msgIds) {
		Map<String, List<Long>> namedParameters = Collections.singletonMap(
				"msgIds", msgIds);
		namedParameterJdbcTemplate.update(DELETE_SQL, namedParameters);
	}
	
	
	/**
	 * 分页获取公告索引
	 * @param idPagination
	 * @return
	 */
	public List<PublicMessageIndex> getMsgIndexs(IdPagination idPagination){
		IdPageSqlHelper helper = IdPageSqlHelper.create(idPagination, "msgId");
		String sql = String.format(QUERY_MSG_INDEX_SQL,
				helper.getPagingSqlCondition(), helper.getSizeSqlCondition());
		Object[] data = null;
		if (helper.getIds().length == 0) {
			data = new Object[] { };
		} else if (helper.getIds().length == 1) {
			data = new Object[] { helper.getIds()[0] };
		} else if (helper.getIds().length == 2) {
			data = new Object[] { helper.getIds()[0], helper.getIds()[1]};
		}
		return jdbcTemplate.query(sql, data, ROW_MAPPER);
	}
	
}
